//
//  KzProgressView.swift
//  Trans
//
//  Created by kologe on 2024/10/19.
//

import SwiftUI
import Combine
import Network
import NetAction

//let GBSize:Double = pow(1000, 3)
//let MBSize:Double = pow(1000, 2)
//let KBSize:Double = 1000

struct KzProgressView: View {
    @Binding var fileTransMesage:FileTransMessage
    @Binding var status:Int // 0:client  1: listener
    
    var body: some View {
        GeometryReader{ geometry in
            HStack{
                ToolTipText(title: fileTransMesage.fileName ?? "nil",isHover:  false).frame(width: geometry.size.width * 0.3)
//                Text(fileTransMesage.fileName ?? "nil").frame(width: geometry.size.width * 0.3)
                Divider()
                    .background(kcolors.lineColor)
                    .padding(.vertical,0)
                VStack{
                    ProgressView(value: getPercent()).offset(y:1)
                    HStack{
                        Text(downloadState())
                            .foregroundColor(fileTransMesage.state != DOWNLOADING ? .red: .blue)
                            .font(.system(size: 10))
                        Spacer()
                        Text("\(getPercent() * 100, specifier: "%.2f")%").font(.system(size: 10))
                        Spacer()
                        //显示速度
                        if(fileTransMesage.state == DOWNLOADING){
                            Text("\(size2StrFormat(dnum:getSpeed()))/s").font(.system(size: 10))
                        }
                        Spacer()
                        //显示下载数据的大小
                        Text("\(fileDownloadString(num: (fileTransMesage.downloadSize) )) / \(fileDownloadString(num: (fileTransMesage.totalSize)! ))").font(.system(size: 10))
                    }.offset(y:-1)
                }
                Divider()
                    .background(kcolors.lineColor)
                    .padding(.vertical,0)
                HStack{
                    if fileTransMesage.state != DOWNLOADCANCEL {
                        Button(action:{
                            openFolderAboutFile(filePath: fileTransMesage.absolutePath ?? "")
//                            openFolderAboutFile(filePath: "/Users/gaozhang/Downloads/新版交易架构图.pdf")
                        }){
                            Image(systemName: "folder")
                                .resizable()
                                .scaledToFit()
                                .frame(width: 10, height: 10)
                        }
                        .nomalStyle()
                        Button(action:{
                            //取消传输
                            cancelFileTrans()
                        }){
                            Image(systemName: "xmark.circle")
                                .resizable()
                                .scaledToFit()
                                .frame(width: 10, height: 10)
                        }
                        .nomalStyle()
                        Button(action:{
                            //暂停传输
                            resumeOrPauseFileTrans()
                        }){
                            if fileTransMesage.state != DOWNLOADPAUSE{
                                Image(systemName: "pause.circle")
                                    .resizable()
                                    .scaledToFit()
                                    .frame(width: 10, height: 10)
                            }else{
                                Image(systemName: "play.circle")
                                    .resizable()
                                    .scaledToFit()
                                    .frame(width: 10, height: 10)
                            }
                        }
                        .nomalStyle()
                    }
                }
            }
        }
    }
    
    
    func getSpeed() -> Double{
        let interval = Date().timeIntervalSince1970 - fileTransMesage.startTime
        return Double(fileTransMesage.downloadSize ) / interval
    }
    
    
    func getPercent() -> Double{
        var percent = Double((fileTransMesage.downloadSize))/Double((fileTransMesage.totalSize)!)
        if percent > 1 {
            percent = 1
        }
        return percent
    }
    
    func downloadState() ->String {
        let percent = getPercent()
        var downloadState:String = "传输中"
        if fileTransMesage.state == DOWNLOADCOMPLETE{
            downloadState = "传输完成"
        }else if fileTransMesage.state == DOWNLOADFAILED{
            downloadState = "传输中断"
        }else if fileTransMesage.state == DOWNLOADCANCEL{
            downloadState = "传输取消"
        }else if fileTransMesage.state == DOWNLOADPAUSE{
            downloadState = "传输暂停"
        }
        else if percent < 1{
            downloadState = "传输中"
        }
        return downloadState
    }
    
    func fileDownloadString(num:UInt64) ->String{
        let dnum = Double(num)
        return size2StrFormat(dnum: dnum)
    }
    
    func openFolderAboutFile(filePath:String){
        if(filePath.isEmpty){
            print("openFolderAboutFile: not file name please open download folder yourself")
            return
        }
        
        var fileURL = URL(fileURLWithPath: filePath)
        fileURL.deleteLastPathComponent()
        if  fileURL.isFileURL {
            NSWorkspace.shared.open(fileURL)
        }else{
            error_log("file is not right path")
        }
        
//        if let fileURL = URL(string: filePath),fileURL.isFileURL{
//            let fileManager = FileManager.default
//            if(!fileManager.fileExists(atPath: fileURL.path)){
//                print("openFolderAboutFile: file not exists")
//                return
//            }
//            let folderURL = fileURL.deletingLastPathComponent()
//            //            openFolder(folderURL)
//            let status = NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: folderURL.path)
//            if(status == true){
//                NSLog("open folder success")
//            }else{
//                NSLog("open folder fail")
//            }
//        }
    }
    
    func openFolder(_ folderURL:URL) {
        let panel = NSOpenPanel()
        panel.canChooseFiles = false
        panel.canChooseDirectories = true
        panel.allowsMultipleSelection = false
        
        if let window = NSApplication.shared.windows.first {
            panel.beginSheetModal(for: window) { response in
                if response == .OK{
                    NSWorkspace.shared.open(folderURL)
                }
            }
        }
    }
    
    //##############################
    func cancelFileTrans(){
        
        //client取消发送，listener ,client 同时设置状态为取消
        fileTransMesage.state = INT32(DOWNLOADCANCEL)
        
        let fileCancel = FileCancel(fileId: fileTransMesage.fileId)
        
        
        var connection:NWConnection? = nil
        if 1 == status{
            //listener 在connectionMessage的filedic中删除，并发送取消文件的信号
            kzListener.conDic[fileTransMesage.conID]?.fileDic.removeValue(forKey: fileTransMesage.fileId)
            //删除文件
            DispatchQueue.global().asyncAfter(deadline: .now() + 1){
                FileController.deleteFile(filePath: fileTransMesage.absolutePath!)
            }
            connection = kzListener.conDic[fileTransMesage.conID]?.con
        }else{
            // client 取消发送，然后发送取消文件的信号，然后从filedic中删除
            fileTransMesage.state = DOWNLOADCANCEL //取消发送
            //获得相应的tcpclient，然后删除相应的filetrademessage
            if let tcpClient = TCPClientManager.shared.clientDic[fileTransMesage.conID] {
                tcpClient.fileDic.removeValue(forKey: fileTransMesage.fileId)
                connection = tcpClient.connection
            }
            
        }
       
        let pkgData =  BaseData.pkgData(obj: fileCancel)
        if connection != nil{
            connection!.send(content: pkgData, completion: .contentProcessed({ error in
                if let error = error{
                    error_log("error: cancelFileTrans -> \(error)")
                }else{
                    print("cancelFileTrans send data success")
                }
            }))
        }
        
    }
    func resumeOrPauseFileTrans(){
        
        //回复传输
        if fileTransMesage.state == DOWNLOADPAUSE{
            resumeFileTrans()
        }else{//暂停传输
            pauseFileTrans()
        }
        
        
    }
    
    func resumeFileTrans(){
        //发送信息，如果接受到了信息才开始执行相关的恢复操作。主要是connection是否还存在的问题，需要有一个数据来保存暂停的队列的conection的ip信息。connection不存在就是断开了链接的情况
        if let fileResume = getResume(),let pkgData = BaseData.pkgData(obj: fileResume){
            var con:NWConnection? = nil
            if 1 == status
            {
                con = kzListener.conDic[fileTransMesage.conID]?.con
            }else{
                let client = TCPClientManager.shared.clientDic[fileTransMesage.conID]
                con = client?.connection
            }
            if let connection = con {
                connection.send(content: pkgData, completion: .contentProcessed({ error in
                    if let error = error{
                        error_log("error: resumeFileTrans -> \(error)")
                    }else{
                        print("resumeFileTrans send data success")
                        fileTransMesage.state = DOWNLOADING
                    }
                }))
            }else{//断开链接的情况下，
                reconnect()
            }
        }
    }
    func getResume() -> FileResume?{
        let fileResume = FileResume(fileId: fileTransMesage.fileId)
        if 1 == status{
            //判断文件是否存在
            if !FileManager.default.fileExists(atPath: fileTransMesage.absolutePath!){
                //弹出显示信息
                let msg = "本地:\(fileTransMesage.fileName!)文件不存在,无法重新传输"
                var view = WarnText(size:NSMakeSize(450, 200));
                view.textStr = msg
                let id = Cal.hashOfString(str: msg)
                view.winId = id
              
                WindowDelegate.openWindow(view: view, title: "warn", size: NSMakeSize(450, 200), id: id)
                return nil
            }
            if let size = FileController.fileSize(filepath: fileTransMesage.absolutePath!){
                fileResume.size = size
                fileTransMesage.downloadSize = size
            }
            
        }
        return fileResume
    }
    
    func pauseFileTrans(){
        //client取消发送，listener ,client 同时设置状态为暂停
        fileTransMesage.state = INT32(DOWNLOADPAUSE)
        
        let fileStop = FileStop(fileId: fileTransMesage.fileId)
       
        if let jsonData =  FileStop.enCodeToJson(obj: fileStop){
            let pkgData = PackageHead.packageData(msgData: jsonData, type: FILE_STOP)
            var con:NWConnection? = nil
            if 1 == status
            {
                con = kzListener.conDic[fileTransMesage.conID]?.con
            }else{
                let client = TCPClientManager.shared.clientDic[fileTransMesage.conID]
                con = client?.connection
            }
            
            if let connection = con{
                connection.send(content: pkgData, completion: .contentProcessed({ error in
                    if let error = error{
                        error_log("error: pauseFileTrans -> \(error)")
                    }else{
                        print("pauseFileTrans send data success")
                        if 1 == status{
                            
                        }else{
                            fileClientPauseArr.add(obj: fileTransMesage)//保存暂停传输的数据的信息
                        }
                    }
                }))
            }
        }
    }
    //重连请求
    func reconnect(){
        info_log("connection was canceled, start reconnect")
        var side = TERMINALSIDE.CLIENT
        if 1 == status{
            side = .LISTENER
        }
        let reconnect = ReConnect(side: INT32(status), type: 0)
        
        if ConContainerMsg.shared.canBeAdd(ip: fileTransMesage.ip, type: reconnect.getType(), side:side){
            ConContainerMsg.shared.addTask(ip:fileTransMesage.ip , side: side, task: reconnect)
            if let fileResume = getResume(){
                ConContainerMsg.shared.addTask(ip:fileTransMesage.ip , side: side, task: fileResume)
            }
            
            TCPClientManager.shared.sendBaseData(ip: fileTransMesage.ip, task: reconnect)
        }
        
    }
    

}

//#Preview {
//    KzProgressView(fileTransMesage: .constant(FileTransMessage()) )
//}
